/**
 * 添加拦截器:
 *   拦截 request 请求
 *   拦截 uploadFile 文件上传
 *
 * TODO:
 *   1. 非 http 开头需拼接地址
 *   2. 请求超时
 *   3. 添加小程序端请求头标识
 *   4. 添加 token 请求头标识
 */

import { useAuthStore } from '@/stores'

const baseURL = import.meta.env.VITE_HTTP_BASE_URL;
const clientId = import.meta.env.VITE_CLIENT_ID;

// 添加拦截器
const httpInterceptor = {
	// 拦截前触发
	invoke(options : UniApp.RequestOptions) {
		// 1. 非 http 开头需拼接地址
		if (!options.url.startsWith('http')) {
			options.url = baseURL + options.url
		}
		// 2. 请求超时, 默认 60s
		options.timeout = 1000 * 60
		// 3. 添加小程序端请求头标识
		options.header = {
			clientId: clientId,
			...options.header,
			'source-client': 'miniapp',
		}
		// 4. 添加 token 请求头标识
		const authStore = useAuthStore()
		const token = authStore.profile?.access_token
		if (token) {
			options.header['Authorization'] = `Bearer ${token}`
		}
	},
}
uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)

/**
 * 请求函数
 * @param  UniApp.RequestOptions
 * @returns Promise
 *  1. 返回 Promise 对象
 *  2. 获取数据成功
 *    2.1 提取核心数据 res.data
 *    2.2 添加类型，支持泛型
 *  3. 获取数据失败
 *    3.1 401错误  -> 清理用户信息，跳转到登录页
 *    3.2 其他错误 -> 根据后端错误信息轻提示
 *    3.3 网络错误 -> 提示用户换网络
 */
type Data<T> = {
	code : number
	msg : string
	data : T
	rows : T
	total : number
}

/**
 * @description:  contentTyp
 */
export enum ContentType {
	// json
	JSON = 'application/json;charset=UTF-8',
	// form-data qs
	FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
	// form-data  upload
	FORM_DATA = 'multipart/form-data;charset=UTF-8',
}


let loading = 0;

/**
 * 支持泛型
 */
export const http = <T>(options : UniApp.RequestOptions & { forceLogin ?: boolean; loading ?: boolean }) => {
	options.forceLogin = options.forceLogin ?? true;
	options.loading = options.loading ?? true;
	if (options.loading) {
		loading++;
		// 1. 返回 Promise 对象
		uni.showLoading({
			title: '加载中'
		});
	}
	return new Promise<Data<T>>((resolve, reject) => {
		uni.request({
			...options,
			// 响应成功
			success(res) {
				// 状态码 2xx， axios 就是这样设计的
				if (res.statusCode >= 200 && res.statusCode < 300) {
					// 2.1 提取核心数据 res.data
					const data = res.data as Data<T>;
					if (data.code === 401) {
						const authStore = useAuthStore();
						authStore.clearProfile();
						authStore.show();
						// if (options.forceLogin) {
						// 	// uni.navigateTo({ url: '/pages/login/login' });

						// }
						reject(data);
						return;
					}
					resolve(data);

					// else if (res.statusCode === 401) {
					// 	// 401错误  -> 清理用户信息，跳转到登录页
					// 	const authStore = useAuthStore()
					// 	authStore.clearProfile()
					// 	uni.navigateTo({ url: '/pages/login/login' })
					// 	reject(res)
					// } 

				} else {
					// 其他错误 -> 根据后端错误信息轻提示
					uni.showToast({
						icon: 'none',
						title: (res.data as Data<T>).msg || '请求错误',
					})
					reject(res)
				}
			},
			// 响应失败
			fail(err) {
				uni.showToast({
					icon: 'none',
					title: '网络错误，换个网络试试',
				})
				reject(err)
			},
			complete() {
				if (options.loading) {
					loading--;
					if (loading <= 0) {
						uni.hideLoading();
					}
				}
			}
		})
	})
}




export const httpFormData = (options : UniApp.RequestOptions) => {
	const header = options.header ?? {};
	header['Content-type'] = ContentType.FORM_DATA;
	const formData = new FormData();

	const append = (key : any, value : any) => {
		if (value instanceof File) {
			const file = value as File;
			formData.append(key, file, file.name);
		} else {
			formData.append(key, value);
		}
	}
	if (options.data) {
		for (const [key, value] of Object.entries(options.data)) {
			if (Array.isArray(value)) {
				append(`${key}[]`, value);
			} else {
				append(key, value);
			}
		}
	}
	return http({
		...options,
		data: formData
	})
}

export function isResultSuccess(res : AnyObj, success = "提交成功") {
	if (res.code !== 200) {
		uni.showToast({
			icon: 'none',
			title: res.msg ?? '服务器忙，请然后再试'
		})
		return false;
	}
	if (success) {
		uni.showToast({
			icon: 'none',
			title: success
		})
	}

	return true;
}